package com.wang.tool.dagre;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wang.tool.common.ErrorInfo;
import com.wang.tool.monitor.LinkLogUtil;
import com.wang.tool.monitor.translator.GlobalErrorTranslator;
import com.wang.tool.common.SimpleException;

import java.util.Map;

/**
 *
 * @Description 图流程结果
 * @Author shaopeng
 * @Date 2022/12/7
 * @Version 1.0
 */
public class DagreResult {

    /**
     * 结果
     */
    private Object data;

    /**
     * 异常结果
     */
    private ErrorInfo error;

    /**
     * 扩展信息
     */
    private JSONObject ext = new JSONObject();


    /*-------------------分割线----------------------*/


    /**
     * 状态码
     * 非空
     * 系统填充
     */
    private StatusEnum status;

    /**
     * 耗时
     * 系统填充
     */
    private int cost;

    /**
     * 结束的节点id
     * 系统填充
     */
    private String finishNodeId;

    /**
     * 节点执行状况
     * 系统填充
     */
    private Map<String, NodeState> nodeStates;


    public static DagreResult buildSuccess(Object data) {
        DagreResult result = new DagreResult();
        result.setData(data);
        return result;
    }

    public static DagreResult buildError(Throwable error) {
        DagreResult result = new DagreResult();
        result.setError(GlobalErrorTranslator.translate(error == null ? new SimpleException(SimpleException.UNKNOWN_ERROR, "未知异常") : error));
        result.setStatus(StatusEnum.ERROR);
        return result;
    }

    public static DagreResult buildError(ErrorInfo error) {
        DagreResult result = new DagreResult();
        result.setError(error == null ? GlobalErrorTranslator.translate(new SimpleException(SimpleException.UNKNOWN_ERROR, "未知异常")) : error);
        result.setStatus(StatusEnum.ERROR);
        return result;
    }

    /**
     * 是否成功
     *
     * @return
     */
    public boolean isSuccess() {
        return getError() == null;
    }


    /**
     * 提取异常类型
     *
     * @return
     */
    public Class fetchErrorType() {
        return error == null ? null : error.getOriginalType();
    }

    /**
     * 提取异常码
     *
     * @return
     */
    public String fetchErrorCode() {
        return error == null ? null : error.getErrorCode();
    }

    /**
     * 提取异常信息
     *
     * @return
     */
    public String fetchErrorMsg() {
        return error == null ? null : error.getErrorMsg();
    }

    /**
     * 取扩展
     *
     * @param key
     */
    public <T> T getExt(String key, Class<T> type) {
        if (key == null || ext == null) {
            return null;
        }
        return type.cast(ext.get(key));
    }

    /**
     * 添加扩展
     *
     * @param key
     * @param val
     */
    public void addExt(String key, Object val) {
        if (key != null) {
            ext = ext == null ? new JSONObject() : ext;
            val = val == null ? LinkLogUtil.EMPTY_PLACEHOLDER : val;
            ext.put(key, val);
        }
    }


    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }


    public ErrorInfo getError() {
        return error;
    }

    public void setError(ErrorInfo error) {
        this.error = error;
    }

    public JSONObject getExt() {
        return ext;
    }

    public void setExt(JSONObject ext) {
        this.ext = ext;
    }


    public int getCost() {
        return cost;
    }

    public void setCost(int cost) {
        this.cost = cost;
    }


    public Map<String, NodeState> getNodeStates() {
        return nodeStates;
    }

    public void setNodeStates(Map<String, NodeState> nodeStates) {
        this.nodeStates = nodeStates;
    }


    public StatusEnum getStatus() {
        return status;
    }

    public void setStatus(StatusEnum status) {
        this.status = status;
    }


    public String getFinishNodeId() {
        return finishNodeId;
    }

    public void setFinishNodeId(String finishNodeId) {
        this.finishNodeId = finishNodeId;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }

    /**
     * @author shaopeng
     * @date 2023/3/25
     */
    public enum StatusEnum {
        /**
         * 全部执行完毕
         */
        ALL_OVER
        /**
         * 某节点返回结果
         */
        , NODE_RETURN
        /**
         * 异常,可能是超时
         * 具体可根据error判断
         */
        , ERROR
        /**
         * 没有需要执行的节点
         */
        , ZERO_NODE
    }
}
